package io.renren.modules.face.utils;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.IdKeyGenerator;
import org.apache.commons.fileupload.FileItem;

import java.io.*;
import java.util.*;

/**
 * 七牛文件上传工具类
 *
 * @author
 * @create 2018-04-04 14:03
 **/
public class QiNiuUploadUtil {
    private static final String AccessKey = "1111";
    private static final String SecretKey = "11";
    private static final String Bucket = "111";

    private static final String Base_Url = "http://xxxxx.com/";

    /**
     * 字节流上传
     *
     * @return
     * @throws Exception
     */
    public static Map<String, String> uploadFileByFilePath(String localFilePath) throws Exception {
        //  构造一个带指定Zone对象的配置类 ，华南
        Configuration cfg = new Configuration(Zone.zone2());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        // 原文件名
        int start = localFilePath.lastIndexOf("\\");
        String fileName = localFilePath.substring(start + 1);
        // 后缀 .jpg
        int indexName = fileName.lastIndexOf('.');
        String subName = fileName.substring(indexName);
        // 新文件名
        String nowName = DateUtils.format(new Date(), DateUtils.DT_YYYYMMDDHHMMSS) + "_" + fileName;

        //默认不指定key的情况下，以文件内容的hash值作为文件名

        String key = "zjimg_" + nowName;
        Auth auth = Auth.create(AccessKey, SecretKey);
        String upToken = auth.uploadToken(Bucket);

        Map<String, String> map = new HashMap<String, String>();
        try {
            Response response = uploadManager.put(localFilePath, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);

            // 现在文件名称
            map.put("title", nowName);
            // 文件原名称
            map.put("original", fileName);
            // 是否上传成功
            map.put("state", "SUCCESS");
            // 文件类型 .+后缀名
            map.put("type", subName);
            // 文件路径
            map.put("url", Base_Url + putRet.key);
            // 文件路径
            map.put("path", putRet.key);
            System.out.println("七牛上传成功：地址----------->" + new Gson().toJson(putRet));
            System.out.println("七牛上传成功：地址----------->" + Base_Url + putRet.key);
            System.out.println("七牛上传成功：hash----------->" + putRet.hash);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.err.println(r.toString());
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
            return null;
        }
        return map;
    }

    /**
     * 字节流上传
     *
     * @return
     * @throws Exception
     */
    public static Map<String, String> uploadFileByBase64(String base64Str) throws Exception {
        String fileName = IdKeyGenerator.uuid() + ".jpg";
        String nowName = DateUtils.format(new Date(), DateUtils.DT_YYYYMMDDHHMMSS) + "_" + fileName;
        String key = "zjimg_" + nowName;
        String filePath = "G:\\3333\\" + key;
        boolean isSuccess = generateFile(base64Str, filePath);
        if (isSuccess) {
            return uploadFileByFilePath(filePath);
        } else {
            return null;
        }
    }

    /**
     * base64字符串转化成文件，可以是JPEG、PNG、TXT和AVI等等
     *
     * @param base64FileStr
     * @param filePath
     * @return
     * @throws Exception
     */
    public static boolean generateFile(String base64FileStr, String filePath) throws Exception {
        // 数据为空
        if (base64FileStr == null) {
            System.out.println(" 不行，oops！ ");
            return false;
        }

        // Base64解码,对字节数组字符串进行Base64解码并生成文件
        byte[] byt = Base64.getDecoder().decode(base64FileStr);
        for (int i = 0, len = byt.length; i < len; ++i) {
            // 调整异常数据
            if (byt[i] < 0) {
                byt[i] += 256;
            }
        }
        OutputStream out = null;
        InputStream input = new ByteArrayInputStream(byt);
        try {
            // 生成指定格式的文件
            out = new FileOutputStream(filePath);
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = input.read(buff)) != -1) {
                out.write(buff, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
        }
        return true;
    }

    /**
     * 字节流上传
     *
     * @param item
     * @return
     * @throws Exception
     */
    public static Map<String, String> uploadByByte(FileItem item, String prefixPath) throws Exception {
        //  构造一个带指定Zone对象的配置类 ，华南
        Configuration cfg = new Configuration(Zone.zone2());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);

        //如果是Windows情况下，格式是 D:\\qiniu\\test.png
        byte[] uploadBytes = item.get();

        // 文件地址名称
        String pathFileName = item.getName();

        //字节数
        long l = item.getSize();
        String fileSize = Long.toString(l);
        // 原文件名
        int start = pathFileName.lastIndexOf("\\");
        String fileName = pathFileName.substring(start + 1);
        // 后缀 .jpg
        int indexName = fileName.lastIndexOf('.');
        String subName = fileName.substring(indexName);
        // 新文件名
        String nowName = DateUtils.format(new Date(), DateUtils.DT_YYYYMMDDHHMMSS) + "_" + fileName;

        //默认不指定key的情况下，以文件内容的hash值作为文件名

        String key = prefixPath + "/" + nowName;
        Auth auth = Auth.create(AccessKey, SecretKey);
        String upToken = auth.uploadToken(Bucket);

        Map<String, String> map = new HashMap<String, String>();
        try {
            Response response = uploadManager.put(uploadBytes, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);

            // 现在文件名称
            map.put("title", nowName);
            // 文件原名称
            map.put("original", fileName);
            // 文件大小（字节数）
            map.put("size", fileSize);
            // 是否上传成功
            map.put("state", "SUCCESS");
            // 文件类型 .+后缀名
            map.put("type", subName);
            // 文件路径
            map.put("url", Base_Url + putRet.key);
            // 文件路径
            map.put("path", putRet.key);
            System.out.println("七牛上传成功：地址----------->" + Base_Url + putRet.key);
            System.out.println("七牛上传成功：hash----------->" + putRet.hash);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.err.println(r.toString());
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
            return null;
        }
        return map;
    }

    /**
     * upload base64-image to qiniu
     *
     * @param imgPath
     */
    public static Map uploadByBase64(String prefixPath, String imgPath) {
        //  构造一个带指定Zone对象的配置类 ，华南
        Configuration cfg = new Configuration(Zone.zone2());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);

        //修改一下ACCESS_KEY 和 SECRET_KEY
        Auth auth = Auth.create(AccessKey, SecretKey);
        //自己修改一下空间名称 - bucketName 和 文件名称 - key
        String upToken = auth.uploadToken(Bucket);
        String key = prefixPath + "/" + randomName() + ".jpg";

        Map<String, String> map = new HashMap<String, String>();
        try {
            byte[] buffer = Base64.getDecoder().decode(imgPath);
            Response response = uploadManager.put(buffer, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);

            // 现在文件名称
//            map.put("title", nowName);
            // 文件原名称
//            map.put("original", fileName);
            // 文件大小（字节数）
//            map.put("size", fileSize);
            // 是否上传成功
            map.put("state", "SUCCESS");
            // 文件类型 .+后缀名
//            map.put("type", subName);
            // 文件路径
            map.put("url", Base_Url + putRet.key);
            // 文件路径
            map.put("path", putRet.key);
            System.out.println("七牛上传成功：地址----------->" + Base_Url + putRet.key);
            System.out.println("七牛上传成功：hash----------->" + putRet.hash);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.err.println(r.toString());
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

    private static String randomName() {
        Random r = new Random();
        int random = r.nextInt();
        String name = DateUtils.format(new Date(), DateUtils.DT_YYYYMMDDHHMMSS) + "_" + String.valueOf(random > 0 ? random : (-1) * random);
        return name;
    }
}
